home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
fwcp
/
src
/
dir.c
< prev
next >
Wrap
Text File
|
1995-03-08
|
8KB
|
384 lines
/***********************************
Dir & File Select
**********************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <jctype.h>
#include <dos.h>
#include "dir.h"
#define TRUE 1
#define FALSE 0
#define ERR (-1)
static int sort_mode = 0;
static struct find_t dma;
static char *strlowcpy(char *dis, register char *s)
{
int ch;
register char *p;
p = dis;
while ( *s != '\0' ) {
ch = *(s++);
if ( iskanji(ch) && iskanji2(*s) ) {
*(p++) = ch;
*(p++) = *(s++);
} else if ( isupper(ch) )
*(p++) = tolower(ch);
else
*(p++) = ch;
}
*p = '\0';
return dis;
}
static char *subname(char *name)
{
while ( *name != '.' && *name != '\0' )
name += (iskan(name) ? 2 : 1);
return name;
}
static int path_cmp(DIRECT *sp, DIRECT *dp)
{
int cd;
if ( (sp->d_att & AT_DIR) != (dp->d_att & AT_DIR) )
return ((sp->d_att & AT_DIR) != 0 ? (-1) : 1);
switch(sort_mode) {
case 0:
cd = strcmp(sp->d_name,dp->d_name);
break;
case 1:
if ( (cd = strcmp(subname(sp->d_name), subname(dp->d_name))) != 0 )
break;
cd = strcmp(sp->d_name,dp->d_name);
break;
case 2:
if ( sp->d_size < dp->d_size )
cd = (-1);
else if ( sp->d_size > dp->d_size )
cd = 1;
else
cd = 0;
break;
case 3:
if ( sp->d_date < dp->d_date )
cd = (-1);
else if ( sp->d_date > dp->d_date )
cd = 1;
else if ( sp->d_time < dp->d_time )
cd = (-1);
else if ( sp->d_time > dp->d_time )
cd = 1;
else
cd = 0;
break;
}
return cd;
}
static DIRECT *dir_sort(DIRECT *np)
{
DIRECT *tp, *bp;
DIRECT *lp, *rp;
if ( np == NULL || np->d_next == NULL )
return np;
lp = rp = NULL;
tp = np->d_next;
while ( tp != NULL ) {
bp = tp->d_next;
if ( path_cmp(np, tp) >= 0 ) {
tp->d_next = lp;
lp = tp;
} else {
tp->d_next = rp;
rp = tp;
}
tp = bp;
}
lp = dir_sort(lp);
rp = dir_sort(rp);
if ( lp != NULL ) {
tp = lp;
while ( lp->d_next != NULL )
lp = lp->d_next;
lp->d_next = np;
} else
tp = np;
np->d_next = rp;
return tp;
}
int dos_stat(char *name, DIRECT *st)
{
if ( _dos_findfirst(name, 0x31, &dma) )
return ERR;
st->d_att = dma.attrib;
st->d_time = dma.wr_time;
st->d_date = dma.wr_date;
st->d_size = dma.size;
strcpy(st->d_name, dma.name);
while ( !_dos_findnext(&dma) )
;
return FALSE;
}
static DIRECT *dir_get(char *sdir, int *st)
{
register DIRECT *np;
char *dir;
DIRECT *top = NULL;
DIRECT *root = NULL;
*st = FALSE;
dir = path_make(sdir, "*.*");
if ( _dos_findfirst(dir, 0x31, &dma) )
goto ENDOF;
do {
if ( strcmp(dma.name, ".") == 0 )
continue;
if ( (np = (DIRECT *)malloc(sizeof(DIRECT))) == NULL ) {
message("opendir %s memory alloc error", sdir);
while ( !_dos_findnext(&dma) )
;
while ( top != NULL ) {
np = top->d_next;
free(top);
top = np;
}
*st = ERR;
return NULL;
}
np->d_next = NULL;
np->d_mark = FALSE;
np->d_att = dma.attrib;
np->d_time = dma.wr_time;
np->d_date = dma.wr_date;
np->d_size = dma.size;
strcpy(np->d_name, dma.name);
if ( strcmp(dma.name, "..") == 0 ) {
if ( root != NULL )
free(root);
root = np;
} else {
np->d_next = top;
top = np;
}
} while ( !_dos_findnext(&dma) );
top = dir_sort(top);
ENDOF:
if ( root != NULL ) {
root->d_next = top;
top = root;
} else if ( strcmp(dir + 1, ":\\*.*") != 0 &&
(np = (DIRECT *)malloc(sizeof(DIRECT))) != NULL ) {
/**********************************************
np->d_mark = FALSE;
np->d_att = 0x10;
np->d_time = 0;
np->d_date = 0;
np->d_size = 0;
strcpy(np->d_name, "..");
np->d_next = top;
top = np;
************************************************/
if ( dos_stat(sdir, np) )
free(np);
else {
np->d_mark = FALSE;
strcpy(np->d_name, "..");
np->d_next = top;
top = np;
}
}
return top;
}
DIR *opendir(char *dir, int mode)
{
int st;
DIR *dirp;
register DIRECT *np;
sort_mode = mode;
if ( (dirp = (DIR *)malloc(sizeof(DIR))) == NULL ) {
message("opendir %s ptr memory alloc error", dir);
return NULL;
}
if ( (dirp->dd_top = dirp->dd_now = dir_get(dir, &st)) == NULL ) {
if ( st == ERR || !isdir(dir) ) {
free(dirp);
return NULL;
}
}
return dirp;
}
DIRECT *readdir(DIR *dirp)
{
DIRECT *np;
if ( (np = dirp->dd_now) != NULL )
dirp->dd_now = np->d_next;
return np;
}
void seekdir(DIR *dirp,int n)
{
DIRECT *np;
np = dirp->dd_top;
while ( n-- > 0 && np != NULL )
np = np->d_next;
dirp->dd_now = np;
}
int countdir(DIR *dirp)
{
int n;
DIRECT *np;
np = dirp->dd_top;
for ( n = 0 ; np != NULL ; n++ )
np = np->d_next;
return n;
}
void closedir(DIR *dirp)
{
DIRECT *np,*tp;
np = dirp->dd_top;
while ( np != NULL ) {
tp = np->d_next;
free(np);
np = tp;
}
free(dirp);
}
int isdir(char *dir)
{
unsigned attr;
if ( dir[0] != '\0' && dir[1] == ':' &&
(dir[2] == '\0' || (dir[2] == '\\' && dir[3] == '\0')) )
return TRUE;
if ( _dos_getfileattr(dir, &attr) )
return FALSE;
return ((attr & 0x10) != 0 ? TRUE:FALSE);
}
char *path_make(char *dir, char *file)
{
char *p;
static char tmp[256];
for ( p = dir ; *p != '\0' ; p++ )
;
if ( *file == '\\' || *dir == '\0' ||
(p != dir && (*(p - 1) == ':' || *(p - 1) == '\\')) )
sprintf(tmp, "%s%s", dir, file);
else
sprintf(tmp, "%s\\%s", dir, file);
return tmp;
}
static int getone(char **ptr)
{
int c;
char *p;
p = *ptr;
c = *(p++);
if ( iskanji(c) && iskanji2(*p) )
c = (c << 8) | (unsigned char)*(p++);
*ptr = p;
return c;
}
static char *wild_rang(char *wild, int fc)
{
int wc, ch;
while ( *wild != '\0' ) {
wc = getone(&wild);
if ( wc == ']' )
return NULL;
if ( *wild == '-' ) {
wild++;
ch = getone(&wild);
if ( ch == ']' ) {
if ( wc <= fc )
goto ENDOF;
} else if ( ch == '\0' )
return NULL;
if ( wc <= fc && fc <= ch )
goto ENDOF;
} else if ( wc == fc )
goto ENDOF;
}
return NULL;
ENDOF:
while ( *wild != '\0' ) {
if ( *(wild++) == ']' )
return wild;
}
return NULL;
}
int wild_mach(char *wild, char *file)
{
int wc, fc;
for ( ; ; ) {
wc = getone(&wild);
fc = getone(&file);
if ( wc == '\0' )
return (fc == '\0' ? TRUE:FALSE);
else if ( wc == '*' ) {
if ( *wild == '\0' )
return TRUE;
for ( file-- ; *file != '\0' ; file++ ) {
if ( wild_mach(wild, file) )
return TRUE;
}
return FALSE;
} else if ( wc == '[' ) {
if ( (wild = wild_rang(wild, fc)) == NULL )
return FALSE;
} else if ( wc != '?' && wc != fc )
return FALSE;
}
}